package com.intramirror.product.service.impl;

import com.intramirror.product.constant.CouponConstant;
import com.intramirror.product.entity.UserCertificate;
import com.intramirror.product.enums.CouponStatusEnum;
import com.intramirror.product.mapper.UserCertificateMapperExt;
import com.intramirror.product.service.ICouponService;
import com.intramirror.product.utils.StringUtils;
import com.intramirror.product.vo.CouponQueryResponseVO;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by 123 on 2018/2/24.
 */
@Service
public class CouponService implements ICouponService {

    private static DateFormat SDF_YYYYMMDD = new SimpleDateFormat("yyyy-MM-dd");
    private static DateFormat SDF_YYYYMMDDHHMMSS = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    @Autowired
    UserCertificateMapperExt userCertificateMapperExt;

    @Override
    public void batchInsertCoupon(List<UserCertificate> userCertificates) {
        userCertificateMapperExt.batchInsert(userCertificates);
    }

    @Override
    public List<CouponQueryResponseVO> queryCouponUserList(Map<String, Object> params) {
        List<Map<String, Object>> couponList = userCertificateMapperExt.queryCouponUserList(params);
        if(CollectionUtils.isEmpty(couponList)) {
            return new ArrayList<>();
        }
        //根据父券id查询子券数据并生成父券ID对子券列表的map，用于计算父券实际使用金额
        List<Long> parentUserCertificateIds = new ArrayList<>();
        for (Map<String, Object> coupon : couponList) {
            parentUserCertificateIds.add(Long.parseLong(coupon.get("user_certificate_id").toString()));
        }
        List<UserCertificate> childCouponList = userCertificateMapperExt.queryChildCouponList(parentUserCertificateIds);
        Map<Long, List<UserCertificate>> parentIdToChildCouponMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(childCouponList)) {
            for (UserCertificate userCertificate : childCouponList) {
                List<UserCertificate> childUserCertificates = parentIdToChildCouponMap.get(userCertificate.getParentCertificateId());
                if (childUserCertificates != null) {
                    childUserCertificates.add(userCertificate);
                } else {
                    childUserCertificates = new ArrayList<>();
                    childUserCertificates.add(userCertificate);
                    parentIdToChildCouponMap.put(userCertificate.getParentCertificateId(), childUserCertificates);
                }
            }
        }
        return generateResponseVOList(couponList, parentIdToChildCouponMap);
    }

    private List<CouponQueryResponseVO> generateResponseVOList(List<Map<String, Object>> couponList, Map<Long, List<UserCertificate>> parentIdToChildCouponMap) {
        List<CouponQueryResponseVO> result = new ArrayList<>();
        for (Map<String, Object> coupon : couponList) {
            CouponQueryResponseVO responseVO = new CouponQueryResponseVO();
            responseVO.setUserCertificateId(Long.parseLong(coupon.get("user_certificate_id").toString()));
            responseVO.setUserName(StringUtils.objToString(coupon.get("username")));
            responseVO.setTelephone(StringUtils.objToString(coupon.get("telephone")));
            responseVO.setReleaseDate(SDF_YYYYMMDD.format(coupon.get("create_at")));
            //代金券父券id（parent_certificate_id）不为空说明是退单新发的券
            responseVO.setCouponType(coupon.get("parent_certificate_id") == null ? CouponConstant.COUPON_TYPE_1 : CouponConstant.COUPON_TYPE_2);
            responseVO.setAmount(coupon.get("amount").toString());

            //计算代金券实际使用金额，用父券金额减去所有子券的金额
            BigDecimal actualUsedAmount = new BigDecimal(coupon.get("amount").toString());
            Long userCertificateId = Long.parseLong(coupon.get("user_certificate_id").toString());
            List<UserCertificate> childUserCertificates = parentIdToChildCouponMap.get(userCertificateId);
            if (CollectionUtils.isNotEmpty(childUserCertificates)) {
                for (UserCertificate childUserCertificate : childUserCertificates) {
                    actualUsedAmount = actualUsedAmount.subtract(new BigDecimal(childUserCertificate.getAmount()));
                }
            }
            responseVO.setActualUsed(actualUsedAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString());

            try {
                //计算代金券使用时间范围
                Calendar calendar = Calendar.getInstance();
                //代金券有效期开始时间
                Date effective_date_start = SDF_YYYYMMDDHHMMSS.parse(coupon.get("effective_date").toString());
                //代金券有效期（秒）
                Long expiration_duration = Long.parseLong(coupon.get("expiration_duration").toString());
                calendar.setTime(effective_date_start);
                calendar.add(Calendar.SECOND, expiration_duration.intValue());
                Date effective_date_end = calendar.getTime();
                responseVO.setEffectiveDateStart(effective_date_start);
                responseVO.setEffectiveDateEnd(effective_date_end);
                responseVO.setEffectiveDate(SDF_YYYYMMDD.format(effective_date_start) + " to " + SDF_YYYYMMDD.format(effective_date_end));

                //过期的券状态都为expired，未过期的券展示实际券状态
                responseVO.setStatus(Integer.parseInt(coupon.get("status").toString()));
                if (effective_date_end.before(new Date())) {
                    responseVO.setStatusStr(CouponStatusEnum.EXPIRED.getStatusStr());
                } else {
                    responseVO.setStatusStr(CouponStatusEnum.getValueByKey(coupon.get("status").toString()).getStatusStr());
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
            responseVO.setUsedAt(coupon.get("used_at") != null ? SDF_YYYYMMDD.format(coupon.get("used_at")) : null);
            responseVO.setRelatedOrderNum(StringUtils.objToString(coupon.get("order_num")));
            responseVO.setOrderAmount(StringUtils.objToString(coupon.get("total_rmb")));
            responseVO.setOrderLogisticsNum(StringUtils.objToString(coupon.get("order_logistics_count")));
            responseVO.setOperator(StringUtils.objToString(coupon.get("operator")));
            result.add(responseVO);
        }

        return result;
    }

    @Override
    public int countCouponUserList(Map<String, Object> params) {
        return userCertificateMapperExt.countCouponUserList(params);
    }
}
